package com.wzapp.sitposture.eshop.endpoint;

import com.wzapp.sitposture.common.constant.PayConst;
import com.wzapp.sitposture.common.error.CustomizedException;
import com.wzapp.sitposture.eshop.pay.properties.AlipayProperties;
import com.wzapp.sitposture.eshop.service.OrderPayService;
import com.wzapp.sitposture.eshop.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 功能: 支付宝支付异步通知Servlet<br/>
 *
 * @author wangzhijun
 *
 **/
public class AliNotifyServlet extends HttpServlet{

    private static final Logger log = LoggerFactory.getLogger(AliNotifyServlet.class);

    private static final long serialVersionUID = -8685285401859800066L;

    private AlipayProperties alipayProperties;

    private ApplicationContext context;

    private OrderPayService orderPayService;

    private OrderService orderService;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        log.debug("----------AliNotifyServlet--->>>>>>>>>>doGet()<<<<<<<<<<<------------");
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        log.debug("----------AliNotifyServlet--->>>>>>>>>>doPost()<<<<<<<<<<<------------");
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");

        PrintWriter out = response.getWriter();

        Map<String, String> params = new HashMap<>(16);
        //getParameterMap()一般多用于接收前台表单多参数传输的数据
        //支付宝的回调都是把信息放到request里面
        Map requestParams = request.getParameterMap();
        //keyset()是获取所有的key值，iterator()是迭代遍历
        for(Iterator iter = requestParams.keySet().iterator();iter.hasNext();){
            String name = (String)iter.next();
            //这里把key放到数组里面
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            //这个for循环的尊用就是把上面那个String中的值都遍历一遍
            for(int i = 0 ; i <values.length;i++){
                //这个是三元运算符
                valueStr = (i == values.length -1)?valueStr + values[i]:valueStr + values[i]+",";
            }
            //把数据全部加进map集合中   name就是key  valueStr就是value
            params.put(name,valueStr);
        }
        //sign就是签名    trade_status是交易的状态
        log.info("支付宝回调,sign:{},trade_status:{},参数:{}",params.get("sign"),params.get("trade_status"),params.toString());

        // 业务处理
        try {

            orderPayService.updateOrderPayed(params.get("out_trade_no"), params.get("trade_no"), PayConst
                    .PAY_METHOD_ALI, "TRADE_SUCCESS".equals(params.get("trade_status")));
        } catch (CustomizedException e) {
            e.printStackTrace();
        }


        //非常重要,验证回调的正确性,是不是支付宝发的.并且呢还要避免重复通知.
        //这个非常重要，但是不知道这个是什么意思
        //这个是签名类型 sign参数已经帮我们删除掉了，在这里我们要把签名类型删除掉
        params.remove("sign_type");
//        try {
//            //这里是RSA验证签名
//            // Configs.getAlipayPublicKey() 其实就是支付宝的应用公钥（记住不是支付宝的公钥，是支付宝应用公钥）
//            //Configs.getSignType()也就是支付宝文本类型里面的签名类型：RSA2
//            boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, alipayProperties.getPublicKeypem(),"utf-8","RSA2");
//            //如果验证上面的boolean为true的话，我们就应该更改下订单的状态，减少下库存这些操作
//            if(!alipayRSACheckedV2){
//                out.println("非法请求,验证不通过,再恶意请求我就报警找网警了");
//            }
//        } catch (AlipayApiException e) {
//            log.error("支付宝验证回调异常",e);
//        }

        out.println("SUCCESS");
    }

    @Override
    public void init() throws ServletException {
        context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        orderPayService = context.getBean(OrderPayService.class);
        alipayProperties = context.getBean(AlipayProperties.class);
        orderService = context.getBean(OrderService.class);
    }

}
